package com.googlecode.garbagecan.neo4jstudy.helloworld;

import java.io.File;
import java.io.IOException;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.kernel.impl.util.FileUtils;

public class Test {
	private static final String DB_PATH = "target/neo4j-hello-db";

	private static GraphDatabaseService graphDB;
	private static Node firstNode;
	private static Node secondNode;
	private static Relationship relationship;

	private static enum MyRelationshipTypes implements RelationshipType {
		KNOWS
	}

	public static void main(final String[] args) {
		Test hello = new Test();
		hello.createDB();
		hello.removeData();
		hello.shutdown();
	}

	private static void createDB() {
		clearDB();

		graphDB = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
		registerShutdownHook(graphDB);

		Transaction tx = graphDB.beginTx();
		try {
			firstNode = graphDB.createNode();
			firstNode.setProperty("message", "Hello, ");
			secondNode = graphDB.createNode();
			secondNode.setProperty("message", "World!");

			relationship = firstNode.createRelationshipTo(secondNode, MyRelationshipTypes.KNOWS);
			relationship.setProperty("message", "brave Neo4j ");

			System.out.print(firstNode.getProperty("message"));
			System.out.print(relationship.getProperty("message"));
			System.out.print(secondNode.getProperty("message"));

			tx.success();
		} finally {
			tx.finish();
		}
	}

	private static void clearDB() {
		try {
			FileUtils.deleteRecursively(new File(DB_PATH));
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	void removeData() {
		Transaction tx = graphDB.beginTx();
		try {
			firstNode.getSingleRelationship(MyRelationshipTypes.KNOWS, Direction.OUTGOING).delete();
			firstNode.delete();
			secondNode.delete();

			tx.success();
		} finally {
			tx.finish();
		}
	}

	private static void shutdown() {
		System.out.println();
		System.out.println("Shutting down database ...");
		graphDB.shutdown();
	}

	private static void registerShutdownHook(final GraphDatabaseService graphDB) {
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				graphDB.shutdown();
			}
		});
	}
}